
package com.yeren.common.tool.encrypt;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;


public class RSA{
	
	public static final String  SIGN_ALGORITHMS = "SHA1WithRSA";
	
	
	/**
	 * * 生成密钥对 *
	 * 
	 * @return KeyPair *
	 * @throws EncryptException
	 */
	public static KeyPair generateKeyPair() throws Exception {
		try {
			KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA",
					new org.bouncycastle.jce.provider.BouncyCastleProvider());
			final int KEY_SIZE = 1024;// 没什么好说的了，这个值关系到块加密的大小，可以更改，但是不要太大，否则效率会低
			keyPairGen.initialize(KEY_SIZE, new SecureRandom());
			KeyPair keyPair = keyPairGen.generateKeyPair();
			
			System.out.println(keyPair.getPrivate());
			System.out.println(keyPair.getPublic());
			
			return keyPair;
		} catch (Exception e) {
			throw new Exception(e.getMessage());
		}
	}
	
	/**
	* RSA签名
	* @param content 待签名数据
	* @param privateKey 商户私钥
	* @param input_charset 编码格式
	* @return 签名值
	*/
	public static String sign(String content, String privateKey, String input_charset)
	{
        try 
        {
        	PKCS8EncodedKeySpec priPKCS8 	= new PKCS8EncodedKeySpec( Base64.decode(privateKey) ); 
        	KeyFactory keyf 				= KeyFactory.getInstance("RSA");
        	PrivateKey priKey 				= keyf.generatePrivate(priPKCS8);

            java.security.Signature signature = java.security.Signature
                .getInstance(SIGN_ALGORITHMS);

            signature.initSign(priKey);
            signature.update( content.getBytes(input_charset) );

            byte[] signed = signature.sign();
            
            return Base64.encode(signed);
        }
        catch (Exception e) 
        {
        	e.printStackTrace();
        }
        
        return null;
    }
	
	/**
	* RSA签名
	* @param content 待签名数据
	* @param privateKey 商户私钥
	* @param input_charset 编码格式
	* @return 签名值
	*/
	public static String sign(String content, PrivateKey privateKey, String input_charset)
	{
        try 
        {

            java.security.Signature signature = java.security.Signature
                .getInstance(SIGN_ALGORITHMS);

            signature.initSign(privateKey);
            signature.update( content.getBytes(input_charset) );

            byte[] signed = signature.sign();
            
            return Base64.encode(signed);
        }
        catch (Exception e) 
        {
        	e.printStackTrace();
        }
        
        return null;
    }
	
	
	/**
	* RSA验签名检查
	* @param content 待签名数据
	* @param sign 签名值
	* @param ali_public_key 支付宝公钥
	* @param input_charset 编码格式
	* @return 布尔值
	*/
	public static boolean verify(String content, String sign, String ali_public_key, String input_charset)
	{
		try 
		{
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
	        byte[] encodedKey = Base64.decode(ali_public_key);
	        PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
            return verify(content,sign,pubKey,input_charset);			
		} 
		catch (Exception e) 
		{
			e.printStackTrace();
		}
		
		return false;
	}
	
	public static boolean verify(String content, String sign, PublicKey pubKey, String input_charset)
	{
		try 
		{
			java.security.Signature signature = java.security.Signature
			.getInstance(SIGN_ALGORITHMS);
		
			signature.initVerify(pubKey);
			signature.update( content.getBytes(input_charset) );
		
			boolean bverify = signature.verify( Base64.decode(sign) );
			return bverify;
			
		} 
		catch (Exception e) 
		{
			e.printStackTrace();
		}
		
		return false;
	}
	
	/**
	* 解密
	* @param content 密文
	* @param private_key 商户私钥
	* @param input_charset 编码格式
	* @return 解密后的字符串
	*/
	public static String decrypt(String content, String private_key, String input_charset) throws Exception {
        PrivateKey prikey = getPrivateKey(private_key);
        return decrypt(content,prikey,input_charset);
    }

	
	public static String decrypt(String content, PrivateKey prikey, String input_charset) throws Exception {

        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, prikey);

        InputStream ins = new ByteArrayInputStream(Base64.decode(content));
        ByteArrayOutputStream writer = new ByteArrayOutputStream();
        //rsa解密的字节大小最多是128，将需要解密的内容，按128位拆开解密
        byte[] buf = new byte[128];
        int bufl;

        while ((bufl = ins.read(buf)) != -1) {
            byte[] block = null;

            if (buf.length == bufl) {
                block = buf;
            } else {
                block = new byte[bufl];
                for (int i = 0; i < bufl; i++) {
                    block[i] = buf[i];
                }
            }

            writer.write(cipher.doFinal(block));
        }

        return new String(writer.toByteArray(), input_charset);
    }

	/**
	 * * 解密 *
	 * 
	 * @param key
	 *            解密的密钥 *
	 * @param raw
	 *            已经加密的数据 *
	 * @return 解密后的明文 *
	 * @throws Exception
	 */
	@SuppressWarnings("static-access")
	public static byte[] decrypt(PrivateKey pk, byte[] raw) throws Exception {
		try {
			Cipher cipher = Cipher.getInstance("RSA",
					new org.bouncycastle.jce.provider.BouncyCastleProvider());
			cipher.init(cipher.DECRYPT_MODE, pk);
			int blockSize = cipher.getBlockSize();
			ByteArrayOutputStream bout = new ByteArrayOutputStream(64);
			int j = 0;

			while (raw.length - j * blockSize > 0) {
				bout.write(cipher.doFinal(raw, j * blockSize, blockSize));
				j++;
			}
			return bout.toByteArray();
		} catch (Exception e) {
			throw new Exception(e.getMessage());
		}
	}
	
	/**
	 * 加密
	 * @param publicKey
	 * @param plainText
	 * @return
	 * @throws Exception
	 */
	public static String encrypt(PublicKey publicKey,String plainText) throws Exception{  
        try {             
        	Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);  
            ByteArrayOutputStream writer = new ByteArrayOutputStream();
            InputStream ins = new ByteArrayInputStream(plainText.getBytes("utf-8"));
            //rsa加密的字节大小最多是117，将需要解密的内容，按117位拆开解密
            byte[] buf = new byte[117];
            int bufl;
            
            while ((bufl = ins.read(buf)) != -1) {
                byte[] block = null;

                if (buf.length == bufl) {
                    block = buf;
                } else {
                    block = new byte[bufl];
                    for (int i = 0; i < bufl; i++) {
                        block[i] = buf[i];
                    }
                }

                writer.write(cipher.doFinal(block));
            }
            return Base64.encode(writer.toByteArray());  
        } catch (InvalidKeyException e) {  
            e.printStackTrace();  
        } catch (IllegalBlockSizeException e) {  
            e.printStackTrace();  
        } catch (BadPaddingException e) {  
            e.printStackTrace();  
        }  
        return null;  
    }  
	
	
	/**
	* 得到私钥
	* @param key 密钥字符串（经过base64编码）
	* @throws Exception
	*/
	public static PrivateKey getPrivateKey(String key) throws Exception {

		byte[] keyBytes;
		
		keyBytes = Base64.decode(key);
		
		PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
		
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		
		PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
		
		return privateKey;
	}
	
    /** 
     * 将string类型的key存成 PublicKey类
     *  
     * @param key 
     *            密钥字符串（经过base64编码） 
     * @throws Exception 
     */  
    public static PublicKey getPublicKey(String key) throws Exception {  
        byte[] keyBytes;  
        keyBytes = Base64.decode(key);  
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);  
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");  
        PublicKey publicKey = keyFactory.generatePublic(keySpec);  
        return publicKey;  
        
        
    }  
    
	 public static byte[] hexStringToBytes(String hexString) {
	        if (hexString == null || hexString.equals("")) {
	            return null;
	        }
	        hexString = hexString.toUpperCase();
	        int length = hexString.length() / 2;
	        char[] hexChars = hexString.toCharArray();
	        byte[] d = new byte[length];
	        for (int i = 0; i < length; i++) {
	            int pos = i * 2;
	            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
	        }
	        return d;
	  }
	 
	 private static byte charToByte(char c) {
	        return (byte) "0123456789ABCDEF".indexOf(c);
	 }
    
    /************************rsa加解密测试代码**************************************/
	@SuppressWarnings("unused")
	public static void main(String[] args) throws Exception{
    	String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCo9+9syyPbhferKO9Ol2p6Y03It1J4KWfXCCvM8DDZp2T7/6rTg64q/0CEuWxOsZQVwKURLHvtzFfhTipvE+6U/eyHwgZt9aMxxelsB86Mjn5u7ZxQd3cyRMH9iHsMgMyWapZST2vwlRnI10j8ATcZhy9mLe3oxfHmfxoZGoB/HwIDAQAB";
    	String privateKey = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKj372zLI9uF96so706XanpjTci3UngpZ9cIK8zwMNmnZPv/qtODrir/QIS5bE6xlBXApREse+3MV+FOKm8T7pT97IfCBm31ozHF6WwHzoyOfm7tnFB3dzJEwf2IewyAzJZqllJPa/CVGcjXSPwBNxmHL2Yt7ejF8eZ/GhkagH8fAgMBAAECgYAhUXqRzmDMudcDljfSHINvjMNaz+NgNHH4cfEJIVfQo3SDSH/r42xlqB2VzmZwAg48V9d00nvBgWjW0a4GZzzFLFrGL9AZFjusTLlM4lfMR0QM7v9NrEsfVWLXYzPXt5IJhN74xontNS0tnKN5P0MJFYi8oBOt7f0jVTogH4HQGQJBANXsehXnCvriX+viD9kZ7qW2YQ7pu699NQhBkh7oNDZh819INCOAUQCco8PG+E53ZBv3TzPKc0iPah2CIUmswBMCQQDKM91dZLjtTqVuO4vkIOdhysOfV3aeerg6sgwWaH5TsTyXK9qrhSxEHQ1tV8hVf9DS9zrWFDSUhWJTBkLcp55FAkBJnQ6F6vOEUdHgQfJiKuJMc+4CS7wiL1vIc4fsysrsy9gLubT3Ynh9VWmlPRrFJaB1Xy0KDWiOV4uUi+sYhzGxAkEAsHop1yxkloHQsu/3vWjWaaydpgGhPtpe1qO1Fw2mTAdhmZMl7BN0OhKdOHSoHa9LpAUxbcz+wy3TTiEl1A3bfQJBAJGG1VsWqxmY5k2dT3+05qyWTzCHlHVg/hbTu/YAwyV9fLKOjfcXKeW7Lr54fvyaYM+YBCUkv7rXZ4QTo/c3uNE=";
    	String iosPCpublicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCDfWU4ailzCze4+aTWVWscozoLGv09joiu9UDCxFpCq8iTjXsJY9bRCX6iN53i5Vr+YQwNsGg00uXhw7ll3e7l7eIye3edqG2TUC+HXJ66/lhn948lf3W83Cn5tb+ZFZa+RKUTcZBmZKcZznvHpRhZo9rIjnrZXLWgrYInY8iewIDAQAB";
    	String iosPCprivateKey ="MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAMIN9ZThqKXMLN7j5pNZVaxyjOgsa/T2OiK71QMLEWkKryJONewlj1tEJfqI3neLlWv5hDA2waDTS5eHDuWXd7uXt4jJ7d52obZNQL4dcnrr+WGf3jyV/dbzcKfm1v5kVlr5EpRNxkGZkpxnOe8elGFmj2siOetlctaCtgidjyJ7AgMBAAECgYEAt56324nvp/rcFoh1vMXSgJvf4y1tddyrxAQSGpAViFyYvZBeC7a6wLRqb3elcl79I691up2FeKWXKKmemfdKTeliD9QIi97avzK7KP9bDShirTNg1mzT13iX7kphC2uG2BKHwvLZuwiRSh8CcU47IqwkutaCgJE59cuX5p/PN/kCQQD+FQSAA6aRW7BCNCqMEAL/Wu2bDyODX0DBy/kKiwLG0o1Cy99cUIHOOe9u3qKN36DhUvfnivx87A2O7KWGeOG1AkEAw4TyIW68rSpB4QPAZL8ff0XTybOkbsm3b64CUYK193VQuvAFhtBw/ZKMulloNoMWIiNI7lkWcvIlZ4iQ0a9RbwJBAJrbJnX7Q57eOgvvjWr2K02FFsHltShRer9i2PNjDBsvoqbuaMDz1FljmBmDmaFMhdou3icB36cnm4/bjXrq2+0CQGWOU5psA5LKpUd0hGWQJJMeOQDGz71AB4j50Hh4NX5gsFs5OxWohVgg2/obYJcYBdIbk9FB8vgnsKgTdm2D6/8CQQC+/E7+H+HHa+rcKrMRKSaNkBRxPm4MLG0WqVYIwlWZy/3Fxb2slBtnNGTTYnYtTkBXkDPv0MhMSGefUSdfLMQ5";
    /*	
    	RSA rsa = new RSA();
    	String prikey = "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAM2L/k+0leMaS/XSt0wOs/qVV0ueploJSe50chMpxBC6hQCVMns4wIg78NWzIr3N2NzH75F9GFn81jVhj/ELcuQKVERut/uuHLNDWV/TWMHYHwLTiTiIN42FQtPUMGq0q5EXKkuE5hLCdIQIkstUJO3B+eEna/RSWwpf33ITHgERAgMBAAECgYEAuGoExiBAZlxekHP4jl2Wrpk0lB0IJTm2QiHpgzXyuguObuJtQ068tr4IqsKoxeAc1KDxWPgCVCJbUdNxoJNkBIdUxdkkiLnaFJ4b4l/QRAC3YxKArUGQuZokEvg/Pkxn6t3OAHIuNyeGpXf2jNEkT6PxVsciXWludKut/mWX740CQQDr2oIy/KNJh+uENAjOUAwBz9sPshA05tIZ8ag/ixSLorxcul/gKApUY/cAzvo01oI0auxqhtS++aYSOl9Y+6wLAkEA3xrB99Y1elwb5FwuzgZvHkI3eniW30O1iI8HXTz+uEPv60djxNO5/iM7r3KbKrMf9OEAIlRfv1rDzbxLy1oc0wJAaSrTGbcrfHM+IoItVwm8gOZVUQdeUKiIEQd/tW3n6GfVRCfa7pIMIRs+Hb8tNHheMM9owguDO/EIC2K592yphwJBANpo+YbEn6nfzjZqwC9VQSbgMCunLhv3zxmW2+C9O6fsak1soBEqLSTMHTwO+DR/E0PJmTYCX5GXK6SXN6Ql3Z0CQQChhHtw/Ori8ZXmoSdB2x2HiCBFTpmxV+aok5SamuyKIuUPIZaJdpyyfC9wg+ojbkllhG9lFBkkAzcEckOD+/5x";
    	String context =" OiQZisS3t0U/IHTP9waVSCEa2wJwoG3pFtNcUVs4pQkzsCO90uYIVUaAEFD3OcDCErdaiFQH7Y8njLVqLgMc0qM+8KRKmntlpEN8xQac/n5hM7e9dPMTbK6x3TJXp5jw7UMrslKQ72/ZoXCEy23q0h/XVqPCxZCyaLv+qbhhkkSF9urL0AHmY3yL9ELpL9ozr99xb6vX9GfE0ZieMDb5TRenK5xquBSNd8BjS8NQ1aAQb5/X8jYv9jLuY9cuTXKSHfIaUhJEscULy7d/7Ob0gjSBIHwUllqXSxrGlfpxTc9vKbFH6sQI7TxY0UqA6UMBpVCXKZFLkZ/iWCnWFBKGjnZW8yH7aXz6BHC+4P1Wrh+peWz0/+obqPFxa233UCqqHIpJRZS18Pd3SHLVFbq7LsVqmGann0Vyvv9yV/XzDIWypjOWrVmMkjY4q0KeYupAUWM702a38qBtW7+hFuagh8DDX8D+8vt/lLRCBqs37aU/BCrSYA5+HEfixV+2rXy/Obk3pAjmcqf9Ks7r4BLk8C/OGbyoN41QFLPJ3Y7GRLT/XYaRldmLbjaq/UcaSyczu4gvwR+ftu2c8m3n2MUp5shPRp+gRvRo0mvLOSMSfTF9GjcnTgTR+ZVqZG5EYjGLN2Wb6c5CprCpW1ZAfnUFc0XYSg+Kfb//wgZ6VxYb4w9h5dzJgFyJg96UNqAvD8s31Vub70a76XP5DfO99UxV8/gNWORyvtt4KeeG8/DFDdBXk6jZj/CCVIVemsC+t+LYEgtL8FJurtCskVzEhskGwqbxLOCO7MRQ5MfSexWMFkmbLNOoy/Ih+6KTtxpT4zyp0wXhtg5UKdrMNPZm7ifkFw==";
    	context = rsa.decrypt(context, prikey, "UTF-8");
    	context = rsa.encrypt(rsa.getPublicKey(publicKey),"ashgfahif");
    	
    	context = "Tp6oqFMD3aPMevMJ32ik1uN5yflQnsVnCCH81fho2cFgW3egtBo2nj97oAIrSdVg0i6OG0KaujnYJEdA2eKVacwrPcIVO39YRriAIl6nDymZgnSxM+fG3EhImWCgJ9RLw0fsQ38d/A+nPHU1ds8jwMDS/SASm293JjMozzYW//3ARAeEizy6tp/NSm1num0ifgzN07aluUuxjivHjJZt8ZVh1hFBDcyBsUrOfovtsc6HXq2HxiPaRiAlPAcEnbAdQ8/td2xmtvm+d6MftZ4JS3vyo1ypQS3GGoWiMx3h7dZGfLdFrQMLgTub79ZSHedqdIna2AGrtAndT+d6E40nXw==";
    	context = rsa.decrypt(context, iosPCprivateKey, "UTF-8");*/
    	
    	
    	String string = "";
    	int i =string.length();
    	string = string.substring(2,11);
    	i = Integer.parseInt(string);
    	System.out.println(i);
    	
    } 

    

}
